package com.atguigu.juc.interview.cf;

import java.util.concurrent.*;

/**
 * @author : leimingchao
 * @date Date : 2021年10月01日 13:25
 */
public class CompletableFutureAPIDemo {

    public static void main(String[] args) throws Exception {

        //m1();

        //m2();

        //m3();

        //m4();

        //m5();

        //m6();


    }

    /**
     * 对计算结果进行合并
     */
    private static void m6() {
        System.out.println(CompletableFuture.supplyAsync(() -> {
            return 10;
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
            return 20;
        }), (r1, r2) -> {
            return r1 + r2;
        }).join());
    }

    /**
     * 对计算速度进行选用
     */
    private static void m5() {
        System.out.println(CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 2;
        }), r -> {
            return r;
        }).join());

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 对计算结果进行消费
     */
    private static void m4() {
        CompletableFuture.supplyAsync(() -> {
            return 1;
        }).thenApply(f -> {
            return f + 2;
        }).thenApply(f -> {
            return f + 3;
        }).thenAccept(r -> System.out.println(r));

        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        //无输入无返回
        System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenRun(() -> {}).join());
        //有输入无返回
        System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenAccept(resultA -> {}).join());
        //有输入有返回
        System.out.println(CompletableFuture.supplyAsync(() -> "resultA").thenApply(resultA -> resultA + " resultB").join());
    }

    /**
     * 对计算结果进行处理
     */
    private static void m3() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(50),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());


        System.out.println(CompletableFuture.supplyAsync(() -> 1)
                .handle((f, e) -> {
                    System.out.println("-------1");
                    int i = 10 / 0;
                    return f + 2;
                }).handle((f, e) -> {
                    System.out.println("--------2");
                    return f + 3;
                })
                .whenComplete((v, e) -> {
                    if (e == null) {
                        System.out.println("-------result:" + v);
                    }
                }).exceptionally(e -> {
                    e.printStackTrace();
                    return null;
                }).join());


        threadPoolExecutor.shutdown();
    }

    /**
     * 对计算结果进行处理
     */
    private static void m2() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(50),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());


        System.out.println(CompletableFuture.supplyAsync(() -> 1)
                .thenApply(f -> {
                    System.out.println("-------1");
                    int i = 10 / 0;
                    return f + 2;
                })
                .thenApply(f -> f + 3)
                .whenComplete((v, e) -> {
                    if (e == null) {
                        System.out.println("-------result:" + v);
                    }
                }).exceptionally(e -> {
                    e.printStackTrace();
                    return null;
                }).join());


        threadPoolExecutor.shutdown();
    }

    /**
     * 获得结果和触发计算
     * @throws InterruptedException
     * @throws ExecutionException
     */
    private static void m1() throws InterruptedException, ExecutionException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 20, 1L,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(50),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        },threadPoolExecutor);

        //阻塞
        // System.out.println(future.get());
        //不阻塞，等待2秒，抛出异常
        // System.out.println(future.get(2,TimeUnit.SECONDS));
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //立即获得结果不阻塞，没有计算完的情况下给一个替代结果；算完的话返回计算完成后的结果
        // System.out.println(future.getNow(9999));
        //complete打断，如果打断成功，返回打断的-44；如果打断失败，返回计算出来的值
        System.out.println(future.complete(-44) + "\t" + future.get());


        threadPoolExecutor.shutdown();
    }
}
